#include <stdio.h>  // for printf
#include <string.h> // for memory operation
#include <stdlib.h>
#include <unistd.h>  // for sleep
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "lwip/sockets.h"
#include "wifi_sta_connect.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"

#define CONFIG_WIFI_SSID "mypc"  //热点名
#define CONFIG_WIFI_PWD "12345678"   //热点密码

#define UDP_CONNECT_IPADDR  "192.168.43.27"     //UDP连接的IP地址
#define UDP_CONNECT_PORT 3861           //UDP连接的端口

#define UDP_LISTEN_PORT           1234 // UDP服务器监听端口

char recvbuf[512] = {0};
const char *qihangsendmsg = "Hello! This is qihang UDP Client!";

#define FAN_GPIO_INDEX 2

void buzzer_set(int enable)
{
     IoTGpioSetOutputVal(FAN_GPIO_INDEX,enable ? 1 : 0);
}

/*任务执行函数，启动UDP客户端*/
static int udp_client_task() {
    int ret = 0;
    
    IoTGpioInit(FAN_GPIO_INDEX);
    IoTGpioSetFunc(FAN_GPIO_INDEX, IOT_GPIO_FUNC_GPIO_2_GPIO);
    IoTGpioSetDir(FAN_GPIO_INDEX,IOT_GPIO_DIR_OUT);

    // 连接wifi
    WifiConnect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);

    sleep(2);

    // 创建socket
    int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (socketfd == -1) {
        printf("udp_client_task: create socket failed!\r\n");
        return -1;
    } else {
        printf("udp_client_task: create socket success!\r\n");
    }

    struct sockaddr_in send_addr = {0};
    struct sockaddr_in srv_addr = {0};
    
    // // 绑定端口
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    srv_addr.sin_port = htons(UDP_LISTEN_PORT);
    ret = bind(socketfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));

    // // 连接服务器端
    send_addr.sin_family = AF_INET;
    send_addr.sin_addr.s_addr = inet_addr(UDP_CONNECT_IPADDR);
    send_addr.sin_port = htons(UDP_CONNECT_PORT);

    // 连接服务器后发送并接收数据
    int sin_size = sizeof(struct sockaddr_in);
    int count = 0;
    while (1)
	{
        char sendMsg[128]={0};
        memset(recvbuf, 0, sizeof(recvbuf));
        count++;

      	if ((ret = recvfrom(socketfd, recvbuf, sizeof(recvbuf), 0, 
        (struct sockaddr *)&send_addr, (socklen_t*)&sin_size)) == -1)
        {
            printf("udp_client_task:recv failed, error is %d\r\n", errno);
        } else {
            printf("recv :%s\r\n", recvbuf);
        }

        if(strstr(recvbuf,"buzzer:")!=NULL)
        {
            if(strcmp(recvbuf+7,"on")==0)
            {
                //buzzer on
                buzzer_set(1);
                sprintf_s(sendMsg,sizeof(sendMsg),"buzzer on ok!");
            }else if(strcmp(recvbuf+7,"off") == 0)
            {
                //buzzer off
                buzzer_set(0);

                sprintf_s(sendMsg,sizeof(sendMsg),"buzzer off ok!");
            }else{
                // unkonow
                sprintf_s(sendMsg,sizeof(sendMsg),"buzzer unsupported cmd!");
            }
        }else{
            sprintf_s(sendMsg,sizeof(sendMsg),"unkonow cmd!");
        }

        // sprintf_s(sendMsg,sizeof(sendMsg),"%s ++ %d\n",send_str,count);
		if ((ret = sendto(socketfd, sendMsg, strlen(sendMsg), 0,
         (struct sockaddr *)&send_addr, sizeof(send_addr))) == -1)
        {
            printf("udp_client_task:send failed, error is %d\r\n", errno);
			break;
        } else {
            printf("send :%s\r\n", sendMsg);
        }
	}

    closesocket(socketfd);
    return 0;
}

void udp_client_demo()
{
    osThreadAttr_t attr;

    attr.name = "WifSTATask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 25;

    if (osThreadNew((osThreadFunc_t)udp_client_task, NULL, &attr) == NULL)
    {
        printf("Falied to create wifi sta!\r\n");
    }
}

APP_FEATURE_INIT(udp_client_demo);